/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package wiiscript;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JComboBox;
import javax.swing.JMenuItem;
import javax.swing.JTextPane;
import javax.swing.plaf.basic.BasicComboPopup;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;
import javax.swing.undo.UndoManager;

/**
 *
 * @author Rob Camick
 */
public class EditorPane extends JTextPane {
    private JComboBox menuItems = new AutoCompleteCombo(this);
    private BasicComboPopup menu = new BasicComboPopup(menuItems);
    private UndoManager undo = new UndoManager();
    private JMenuItem undoMenu;
    private JMenuItem redoMenu;

    private ArrayList<Integer> results = new ArrayList<Integer>();
    private StyleContext sc = new StyleContext();
    private Style findStyle = sc.addStyle("findStyle", null);
    private Style selectedStyle = sc.addStyle("selectedStyle", null);
    private int nextIndex = 0;
    private int wordLength = 0;

    public EditorPane() {
        addKeyListener(new PropertyListener());
        LinePainter linePainter = new LinePainter(this);
        linePainter.setColor(new Color(230, 230, 255)); 
    }
    public void setUndo(JMenuItem undo) {
        undoMenu = undo;
    }
    public void setRedo(JMenuItem redo) {
        redoMenu = redo;
    }
    private void checkCodeCompletion() throws BadLocationException {
        String text = getText();
        String substring = "";
        for(int i = text.length() - 1; i >= 0; i--) {
            if(text.charAt(i) != ' ' && text.charAt(i) != '\n') {
                substring = text.charAt(i) + substring;
            } else {
                break;
            }
        }
        substring = substring.toLowerCase();
        String[] properties = Properties.getProperties(substring);
        if(properties != null) {
            displayCodeCompletion(properties);
        } else {
            menu.setVisible(false);
        }
    }
    public void hideCodeComplete() {
        menu.setVisible(false);
    }
    public void addLine(String line) {
        StyledDocument doc = getStyledDocument();
        setCaretPosition(doc.getLength());
        replaceSelection(line + "\n");
    }
    public void removeLine(String line) {
        String text = getText();
        text = text.replaceFirst(line + System.getProperty("line.separator"), "");
        this.setText(text);
    }
    private void displayCodeCompletion(String[] values) throws BadLocationException {
        //First entry is not displaying:
        String[] nValues = new String[values.length + 1];
        for(int i = 0; i < values.length; i++) {
            nValues[i + 1] = values[i];
        }

        ((AutoCompleteCombo)menuItems).setData(nValues);
        Rectangle caretPosition = modelToView(getCaretPosition());
        Point panePosition = getLocationOnScreen();
        Point totalPosition = new Point(caretPosition.x + panePosition.x -5,
                                        caretPosition.y + panePosition.y + 20);
        menu.setLocation(totalPosition);
        menu.setVisible(true);
        menu.requestFocus();
    }
    public void find(String find, boolean wholeWord) {
        String text = getText();
        wordLength = find.length();
        //Clear previous find
        results.clear();
        findStyle.addAttribute(StyleConstants.Background, new Color(0, 0, 0, 0));
        getStyledDocument().setCharacterAttributes(0, wordLength, findStyle, false);

        //Find words
        int index = text.indexOf(find);
        while(index != -1) {
            results.add(index);
            index = text.indexOf(find, index + 1);
        }
        //Highlight found words
        findStyle.addAttribute(StyleConstants.Background, Color.LIGHT_GRAY);
        for(int wordIndex : results) {
            getStyledDocument().setCharacterAttributes(wordIndex, find.length(), findStyle, false);
        }
        nextIndex = 0; //Reset findNext

    }
    public void findNext() {
        //Clear Last Find
        int lastIndex = nextIndex - 1;
        if(lastIndex < 0) lastIndex = results.size() - 1;
        getStyledDocument().setCharacterAttributes(lastIndex, getText().length(), findStyle, false);

        if(results.size() == 0) return; //Nothing to find

        selectedStyle.addAttribute(StyleConstants.Background, Color.ORANGE);
        getStyledDocument().setCharacterAttributes(results.get(nextIndex), wordLength, selectedStyle, false);
        nextIndex++;
        if(nextIndex >= results.size()) nextIndex = 0;
    }
    @Override
    public void setSize(Dimension d) {
	if (d.width < getParent().getSize().width)
            d.width = getParent().getSize().width;

	super.setSize(d);
    }

    @Override
    public boolean getScrollableTracksViewportWidth() {
	return false;
    }
    private class PropertyListener implements KeyListener {
        public void keyTyped(KeyEvent e) {
        }
        public void keyPressed(KeyEvent e) {
            if(e.getKeyCode() == KeyEvent.VK_PERIOD) {
                try {
                    checkCodeCompletion();
                } catch (BadLocationException ex) {
                    Logger.getLogger(EditorPane.class.getName()).log(Level.SEVERE, null, ex);
                }
            } else {
                menu.setVisible(false);
            }
        }

        public void keyReleased(KeyEvent e) {
        }
    }
}
